﻿using System;
using System.Collections.Generic;
using System.Linq;
using Maltose.Encrypt;

namespace Maltose.MicroService
{
    /// <summary>
    /// 扩展微服务签名
    /// </summary>
    public static class ToMicroServiceSignExtension
    {
        /// <summary>
        /// 返回application/form-data拼接的数据参数
        /// </summary>
        /// <param name="pairs"></param>
        /// <returns></returns>
        public static string ToFormData(this Dictionary<string, object> pairs)
        {
            return string.Join("&", pairs.Select(t => string.Format("{0}={1}", t.Key, t.Value)));
        }

        /// <summary>
        /// 获取带有签名的参数
        /// </summary>
        /// <param name="pairs">参数</param>
        /// <param name="apiKey">apikey</param>
        /// <param name="password">密钥</param>
        /// <param name="sing">是否追加sign</param>
        /// <returns></returns>
        public static string ToMicroServiceData(this Dictionary<string, object> pairs, string apiKey, string password, bool sing = true)
        {
            pairs.TryAdd("apikey", apiKey);
            pairs.TryAdd("version", "1.0");
            if (sing)
            {
                if (string.IsNullOrWhiteSpace(apiKey))
                {
                    throw new ArgumentNullException("使用微服务签名认证时，apiKey 值不能为空");
                }
                if (string.IsNullOrWhiteSpace(password))
                {
                    throw new ArgumentNullException("使用微服务签名认证时，password 值不能为空");
                }
                pairs.TryAdd("sign", pairs.ToMicroServiceSign(password));
            }
            return string.Join("&", pairs.Select(t => string.Format("{0}={1}", t.Key, t.Value)));
        }

        /// <summary>
        /// 转换成微服务请求的 签名包
        /// </summary>
        /// <param name="pairs">参数</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        static string ToMicroServiceSign(this Dictionary<string, object> pairs, string password)
        {
            var parametorsSort = pairs.OrderBy(x => x.Key, StringComparer.Ordinal);
            string signStr = string.Join("&", parametorsSort.Select(t => string.Format("{0}={1}", t.Key, t.Value))) + password;
            return MD5Encrypt.EncryptToLower(signStr);
        }
    }
}
